package edu.hawaii.stack;

import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;

import org.junit.Test; 
import java.util.ArrayList;

/**
 * Test case for the ClearStack abstract data type, which checks to see that a ClearStack
 * containing three elements can be iterated through and that this iteration retrieves the
 * elements in the correct order. 
 *
 * @author Philip Johnson
 */
public class TestClearStack {

  // Objects used for testing.
  private final Integer one = Integer.valueOf(1);
  private final Integer two = Integer.valueOf(2);
  private final Integer three = Integer.valueOf(3);
// atshum: replaced the 3 lines below with the 3 lines above
// private Integer one = new Integer(1);
// private Integer two = new Integer(2);
// private Integer three = new Integer(3);

  /**
   * Test the ClearStack iterator.
   */
  @Test
  public void testNormalOperation() {
    ClearStack stack = new ClearStack();
    stack.push(one);
    stack.push(two);
    stack.push(three);
    ArrayList<Object> list = new ArrayList<Object>();
    // Go through the elements in the stack and save them in an ArrayList.
    for (Object element : stack) {
      list.add(element);
    }
    // Now check to see they were there and in the right order.
    assertSame("Testing ClearStack[0]", one, list.get(0));
    assertSame("Testing ClearStack[1]", two, list.get(1));
    assertSame("Testing ClearStack[2]", three, list.get(2));
  }
  
// atshum: added below to get 100% coverage.
  /**
   * Test the getTop method under normal operation.
   * 
   * @throws EmptyStackException If the stack is empty when pop is called.
   */
  @Test
  public void testGetTop() throws EmptyStackException {
    ClearStack stack = new ClearStack();
    stack.push(one);
    stack.push(two);
    stack.push(three);
    // Test to see if getTop returns the correct value.
    assertSame("Testing getTop of three", three, stack.getTop());
    stack.pop();
    assertSame("Testing getTop of two", two, stack.getTop());
    stack.pop();
    assertSame("Testing getTop of one", one, stack.getTop());
  }

// atshum: added below to get 100% coverage.
  /**
   * Test the getTop method when the stack is empty.
   * The getTop method should throw an exception when the stack is empty.
   * 
   * @throws EmptyStackException If the stack is empty when top is called.
   */
  @Test (expected = EmptyStackException.class)
  public void testIllegalGetTop() throws EmptyStackException {
    ClearStack stack = new ClearStack();
    stack.getTop();
  }
  
// atshum: added below to get 100% coverage.
  /**
   * Test the isEmpty method.
   * 
   * @throws EmptyStackException If the stack is empty when pop is called.
   */
  @Test
  public void testIsEmpty() throws EmptyStackException {
    ClearStack stack = new ClearStack();
    // Test if a new stack is initially empty.
    assertTrue("Testing isEmpty of true", stack.isEmpty());
    stack.push(one);
    // Test if the stack is no longer empty.
    assertFalse("Testing isEmpty of false", stack.isEmpty());
    stack.pop();
    // Test if the stack is empty again.
    assertTrue("Testing isEmpty of true", stack.isEmpty());    
  }

}
